/**
 * @param {number} n
 * @param {number[][]} meetings
 * @param {number} firstPerson
 * @return {number[]}
 */
 var findAllPeople = function(n, meetings, firstPerson) {
  const ds = new DisjointSet(n)
  ds.union(firstPerson, 0)
  meetings.sort((a,b) => a[2] - b[2])
  let last = 0, memo = []
  for(let [x, y, t] of meetings){
      if(last !== t){
          for(let x of memo){
              // 重置上个时间不知道秘密的会议成员
              if(ds.findParent(x) !== ds.findParent(0)){
                  ds.parent[x] = x
              }
          }
          memo = []
          last = t
      }
      memo.push(x,y)
      ds.union(x,y)
  }
  const ret = []
  for(let i = 0; i<n; i++){
    if(ds.isConnected(i, 0)) ret.push(i)
  }
  return ret
};

// 并查集
class DisjointSet{
  constructor(n){
      this.parent = new Array(n).fill(0).map((_,idx) => idx)
      // 以i为根结点的子集大小
      this.size = new Array(n).fill(1)
      // 子集个数
      this.count = n
  }
  // 查找根元素
  findParent(x){
      if(this.parent[x] === x) return x
      return this.findParent(this.parent[x])
  }
  // 合并a、b集合
  union(a, b){
      const { parent, size } = this
      let x = this.findParent(a), y = this.findParent(b)
      if(x !== y){
          if(size[x] < size[y]){
              [x, y] = [y, x]
          }
          parent[y] = x
          size[x] += size[y];
          this.count -= 1
          return true
      }
      return false
  }
  // a、b集合是否相连
  isConnected(a, b){
      return this.findParent(a) === this.findParent(b)
  } 
}